using System;
using System.IO;
namespace IcsSEMCtrl.Util
{
	public class StreamTokenizer
	{
		private const byte CT_WHITESPACE = 1;
		private const byte CT_DIGIT = 2;
		private const byte CT_ALPHA = 4;
		private const byte CT_QUOTE = 8;
		private const byte CT_COMMENT = 16;
		public const int TT_EOF = -1;
		public const int TT_EOL = 10;
		public const int TT_NUMBER = -2;
		public const int TT_WORD = -3;
		private const int TT_NOTHING = -4;
		private TextReader reader = null;
		private Stream input = null;
		private char[] buf = new char[20];
		private int peekc = StreamTokenizer.NEED_CHAR;
		private static readonly int NEED_CHAR = 2147483647;
		private static readonly int SKIP_LF = 2147483646;
		private bool pushedBack;
		private bool forceLower;
		private int LINENO = 1;
		private bool eolIsSignificantP = false;
		private bool slashSlashCommentsP = false;
		private bool slashStarCommentsP = false;
		private byte[] ctype = new byte[256];
		public int ttype = -4;
		public string sval;
		public double nval;
		private StreamTokenizer()
		{
			this.WordChars(97, 122);
			this.WordChars(65, 90);
			this.WordChars(160, 255);
			this.WhitespaceChars(0, 32);
			this.CommentChar(47);
			this.QuoteChar(34);
			this.QuoteChar(39);
			this.ParseNumbers();
		}
		public StreamTokenizer(Stream _is) : this()
		{
			if (_is == null)
			{
				throw new NullReferenceException();
			}
			this.input = _is;
		}
		public StreamTokenizer(TextReader r) : this()
		{
			if (r == null)
			{
				throw new NullReferenceException();
			}
			this.reader = r;
		}
		public void ResetSyntax()
		{
			int num = this.ctype.Length;
			while (--num >= 0)
			{
				this.ctype[num] = 0;
			}
		}
		public void WordChars(int low, int hi)
		{
			if (low < 0)
			{
				low = 0;
			}
			if (hi >= this.ctype.Length)
			{
				hi = this.ctype.Length - 1;
			}
			while (low <= hi)
			{
				byte[] arg_38_0 = this.ctype;
				int expr_33 = low++;
				arg_38_0[expr_33] |= 4;
			}
		}
		public void WhitespaceChars(int low, int hi)
		{
			if (low < 0)
			{
				low = 0;
			}
			if (hi >= this.ctype.Length)
			{
				hi = this.ctype.Length - 1;
			}
			while (low <= hi)
			{
				this.ctype[low++] = 1;
			}
		}
		public void OrdinaryChars(int low, int hi)
		{
			if (low < 0)
			{
				low = 0;
			}
			if (hi >= this.ctype.Length)
			{
				hi = this.ctype.Length - 1;
			}
			while (low <= hi)
			{
				this.ctype[low++] = 0;
			}
		}
		public void OrdinaryChar(int ch)
		{
			if (ch >= 0 && ch < this.ctype.Length)
			{
				this.ctype[ch] = 0;
			}
		}
		public void CommentChar(int ch)
		{
			if (ch >= 0 && ch < this.ctype.Length)
			{
				this.ctype[ch] = 16;
			}
		}
		public void QuoteChar(int ch)
		{
			if (ch >= 0 && ch < this.ctype.Length)
			{
				this.ctype[ch] = 8;
			}
		}
		public void ParseNumbers()
		{
			for (int i = 48; i <= 57; i++)
			{
				byte[] expr_12_cp_0 = this.ctype;
				int expr_12_cp_1 = i;
				expr_12_cp_0[expr_12_cp_1] |= 2;
			}
			byte[] expr_3D_cp_0 = this.ctype;
			int expr_3D_cp_1 = 46;
			expr_3D_cp_0[expr_3D_cp_1] |= 2;
			byte[] expr_58_cp_0 = this.ctype;
			int expr_58_cp_1 = 45;
			expr_58_cp_0[expr_58_cp_1] |= 2;
		}
		public void EolIsSignificant(bool flag)
		{
			this.eolIsSignificantP = flag;
		}
		public void SlashStarComments(bool flag)
		{
			this.slashStarCommentsP = flag;
		}
		public void SlashSlashComments(bool flag)
		{
			this.slashSlashCommentsP = flag;
		}
		public void LowerCaseMode(bool fl)
		{
			this.forceLower = fl;
		}
		private int Read()
		{
			int result;
			if (this.reader != null)
			{
				result = this.reader.Read();
			}
			else
			{
				if (this.input == null)
				{
					throw new IOException();
				}
				result = -1;
			}
			return result;
		}
		public int NextToken()
		{
			int result;
			if (this.pushedBack)
			{
				this.pushedBack = false;
				result = this.ttype;
			}
			else
			{
				byte[] array = this.ctype;
				this.sval = null;
				int num = this.peekc;
				if (num < 0)
				{
					num = StreamTokenizer.NEED_CHAR;
				}
				if (num == StreamTokenizer.SKIP_LF)
				{
					num = this.Read();
					if (num < 0)
					{
						result = (this.ttype = -1);
						return result;
					}
					if (num == 10)
					{
						num = StreamTokenizer.NEED_CHAR;
					}
				}
				if (num == StreamTokenizer.NEED_CHAR)
				{
					num = this.Read();
					if (num < 0)
					{
						result = (this.ttype = -1);
						return result;
					}
				}
				this.ttype = num;
				this.peekc = StreamTokenizer.NEED_CHAR;
				int num2 = (int)((num < 256) ? array[num] : 4);
				while ((num2 & 1) != 0)
				{
					if (num == 13)
					{
						this.LINENO++;
						if (this.eolIsSignificantP)
						{
							this.peekc = StreamTokenizer.SKIP_LF;
							result = (this.ttype = 10);
							return result;
						}
						num = this.Read();
						if (num == 10)
						{
							num = this.Read();
						}
					}
					else
					{
						if (num == 10)
						{
							this.LINENO++;
							if (this.eolIsSignificantP)
							{
								result = (this.ttype = 10);
								return result;
							}
						}
						num = this.Read();
					}
					if (num < 0)
					{
						result = (this.ttype = -1);
						return result;
					}
					num2 = (int)((num < 256) ? array[num] : 4);
				}
				if ((num2 & 2) != 0)
				{
					bool flag = false;
					if (num == 45)
					{
						num = this.Read();
						if (num != 46 && (num < 48 || num > 57))
						{
							this.peekc = num;
							result = (this.ttype = 45);
							return result;
						}
						flag = true;
					}
					double num3 = 0.0;
					int i = 0;
					int num4 = 0;
					while (true)
					{
						if (num == 46 && num4 == 0)
						{
							num4 = 1;
						}
						else
						{
							if (48 > num || num > 57)
							{
								break;
							}
							num3 = num3 * 10.0 + (double)(num - 48);
							i += num4;
						}
						num = this.Read();
					}
					this.peekc = num;
					if (i != 0)
					{
						double num5 = 10.0;
						for (i--; i > 0; i--)
						{
							num5 *= 10.0;
						}
						num3 /= num5;
					}
					this.nval = (flag ? (-num3) : num3);
					result = (this.ttype = -2);
				}
				else
				{
					if ((num2 & 4) != 0)
					{
						int num6 = 0;
						do
						{
							if (num6 >= this.buf.Length)
							{
								char[] destinationArray = new char[this.buf.Length * 2];
								Array.Copy(this.buf, 0, destinationArray, 0, this.buf.Length);
								this.buf = destinationArray;
							}
							this.buf[num6++] = (char)num;
							num = this.Read();
							num2 = (int)((num < 0) ? 1 : ((num < 256) ? array[num] : 4));
						}
						while ((num2 & 6) != 0);
						this.peekc = num;
						this.sval = new string(this.buf, 0, num6);
						if (this.forceLower)
						{
							this.sval = this.sval.ToLower();
						}
						result = (this.ttype = -3);
					}
					else
					{
						if ((num2 & 8) != 0)
						{
							this.ttype = num;
							int num6 = 0;
							int num7 = this.Read();
							while (num7 >= 0 && num7 != this.ttype && num7 != 10 && num7 != 13)
							{
								if (num7 == 92)
								{
									num = this.Read();
									int num8 = num;
									if (num >= 48 && num <= 55)
									{
										num -= 48;
										int num9 = this.Read();
										if (48 <= num9 && num9 <= 55)
										{
											num = (num << 3) + (num9 - 48);
											num9 = this.Read();
											if (48 <= num9 && num9 <= 55 && num8 <= 51)
											{
												num = (num << 3) + (num9 - 48);
												num7 = this.Read();
											}
											else
											{
												num7 = num9;
											}
										}
										else
										{
											num7 = num9;
										}
									}
									else
									{
										int num10 = num;
										if (num10 <= 102)
										{
											switch (num10)
											{
											case 97:
												num = 7;
												break;
											case 98:
												num = 8;
												break;
											default:
												if (num10 == 102)
												{
													num = 12;
												}
												break;
											}
										}
										else
										{
											if (num10 != 110)
											{
												switch (num10)
												{
												case 114:
													num = 13;
													break;
												case 116:
													num = 9;
													break;
												case 118:
													num = 11;
													break;
												}
											}
											else
											{
												num = 10;
											}
										}
										num7 = this.Read();
									}
								}
								else
								{
									num = num7;
									num7 = this.Read();
								}
								if (num6 >= this.buf.Length)
								{
									char[] destinationArray = new char[this.buf.Length * 2];
									Array.Copy(this.buf, 0, destinationArray, 0, this.buf.Length);
									this.buf = destinationArray;
								}
								this.buf[num6++] = (char)num;
							}
							this.peekc = ((num7 == this.ttype) ? StreamTokenizer.NEED_CHAR : num7);
							this.sval = new string(this.buf, 0, num6);
							result = this.ttype;
						}
						else
						{
							if (num == 47 && (this.slashSlashCommentsP || this.slashStarCommentsP))
							{
								num = this.Read();
								if (num == 42 && this.slashStarCommentsP)
								{
									int num11 = 0;
									while ((num = this.Read()) != 47 || num11 != 42)
									{
										if (num == 13)
										{
											this.LINENO++;
											num = this.Read();
											if (num == 10)
											{
												num = this.Read();
											}
										}
										else
										{
											if (num == 10)
											{
												this.LINENO++;
												num = this.Read();
											}
										}
										if (num < 0)
										{
											result = (this.ttype = -1);
											return result;
										}
										num11 = num;
									}
									result = this.NextToken();
								}
								else
								{
									if (num == 47 && this.slashSlashCommentsP)
									{
										while ((num = this.Read()) != 10 && num != 13 && num >= 0)
										{
										}
										this.peekc = num;
										result = this.NextToken();
									}
									else
									{
										if ((array[47] & 16) != 0)
										{
											while ((num = this.Read()) != 10 && num != 13 && num >= 0)
											{
											}
											this.peekc = num;
											result = this.NextToken();
										}
										else
										{
											this.peekc = num;
											result = (this.ttype = 47);
										}
									}
								}
							}
							else
							{
								if ((num2 & 16) != 0)
								{
									while ((num = this.Read()) != 10 && num != 13 && num >= 0)
									{
									}
									this.peekc = num;
									result = this.NextToken();
								}
								else
								{
									result = (this.ttype = num);
								}
							}
						}
					}
				}
			}
			return result;
		}
		public void PushBack()
		{
			if (this.ttype != -4)
			{
				this.pushedBack = true;
			}
		}
		public int Lineno()
		{
			return this.LINENO;
		}
		public override string ToString()
		{
			int num = this.ttype;
			string text;
			switch (num)
			{
			case -4:
				text = "NOTHING";
				break;
			case -3:
				text = this.sval;
				break;
			case -2:
				text = "n=" + this.nval;
				break;
			case -1:
				text = "EOF";
				break;
			default:
				if (num != 10)
				{
					if (this.ttype < 256 && (this.ctype[this.ttype] & 8) != 0)
					{
						text = this.sval;
					}
					else
					{
						char[] array = new char[3];
						array[0] = (array[2] = '\'');
						array[1] = (char)this.ttype;
						text = new string(array);
					}
				}
				else
				{
					text = "EOL";
				}
				break;
			}
			return string.Concat(new object[]
			{
				"Token[",
				text,
				"], line ",
				this.LINENO
			});
		}
	}
}
